import React from 'react'

// 高阶组件实现 state 与操作 state 的逻辑的复用
// 高阶组件命名一般以 with 开头
function withMouse(WrapComponent) {
  class Mouse extends React.Component {
    state = {
      x: 0,
      y: 0
    }
      // 组件挂载完成后
    componentDidMount() {
      window.addEventListener('mousemove', this.moveHandler)
    }
    // 组件将要卸载时移除事件
    componentWillUnmount() {
      window.removeEventListener('mousemove', this.moveHandler)
    }
    // 获取鼠标移动坐标值
    moveHandler = e => {
      this.setState({
        x: e.clientX,
        y: e.clientY
      })
    }

    render() {
      return (
        <WrapComponent {...this.props} {...this.state} />
      );
    }
  }
  // 设置 displayName 可以在解决传进来的组件全部变为 Mouse 组件的问题,调试工具中显示 displayName
  Mouse.displayName = `WithMouse${getDisplayName(WrapComponent)}`

  function getDisplayName(WrapComponent) {
    return WrapComponent.displayName || WrapComponent.name || 'Component'
  }
  return Mouse
}

function ShowMouse(props) {
  return (
    <div>编号: { props.id }鼠标当前的位置X: {props.x}, Y: { props.y }</div>
  )
}

function MoveBox(props) {
  return (
    <div style={{ width: 100, height: 100, background: 'red', position: 'absolute', left: props.x, top: props.y }}>{props.name}{ props.age }</div>
  )
}
const MouseShow = withMouse(ShowMouse)
const BoxMove = withMouse(MoveBox)

export default class Hoc extends React.Component {
  render() {
    return (
      <div>
        <MouseShow id={1} />
        <BoxMove name="我是谁" age={25} />
       </div>
    );
  }
}